"""
账户管理器

负责账户信息的管理和维护
"""

import os
import json
import time
from typing import Dict, Any, Optional
from ..core import unified_logger
from ..core.exceptions import AccountError, ValidationError


class AccountManager:
    """账户管理器"""
    
    def __init__(self, storage_path: str = "./data"):
        """
        初始化账户管理器
        
        Args:
            storage_path: 数据存储路径
        """
        self.storage_path = storage_path
        self.accounts_file = os.path.join(storage_path, "accounts.json")
        self.logger = unified_logger.get_logger('account_manager')
        
        # 创建存储目录
        os.makedirs(storage_path, exist_ok=True)
        
        # 账户信息缓存
        self._accounts_cache: Dict[str, Dict[str, Any]] = {}
        
        # 加载现有账户信息
        self._load_accounts()
    
    def _load_accounts(self) -> None:
        """从文件加载账户信息"""
        try:
            if os.path.exists(self.accounts_file):
                with open(self.accounts_file, 'r', encoding='utf-8') as f:
                    self._accounts_cache = json.load(f)
                
                self.logger.info(f"加载了 {len(self._accounts_cache)} 个账户信息")
            else:
                self.logger.info("账户文件不存在，创建新的账户缓存")
                
        except Exception as e:
            self.logger.error(f"加载账户信息失败: {e}")
            self._accounts_cache = {}
    
    def _save_accounts(self) -> None:
        """保存账户信息到文件"""
        try:
            with open(self.accounts_file, 'w', encoding='utf-8') as f:
                json.dump(self._accounts_cache, f, indent=2, ensure_ascii=False)
                
        except Exception as e:
            self.logger.error(f"保存账户信息失败: {e}")
    
    def update_spot_balance(self, exchange: str, balance_data: Dict[str, Any]) -> bool:
        """
        更新现货账户余额
        
        Args:
            exchange: 交易所名称
            balance_data: 余额数据
            
        Returns:
            是否更新成功
        """
        try:
            account_key = f"{exchange}_spot"
            
            if account_key not in self._accounts_cache:
                self._accounts_cache[account_key] = {
                    'exchange': exchange,
                    'account_type': 'spot',
                    'balances': {},
                    'last_update': 0
                }
            
            # 更新余额信息
            self._accounts_cache[account_key]['balances'] = balance_data.get('balances', {})
            self._accounts_cache[account_key]['last_update'] = balance_data.get('update_time', int(time.time()))
            
            # 保存到文件
            self._save_accounts()
            
            self.logger.info(f"更新 {exchange} 现货账户余额成功")
            return True
            
        except Exception as e:
            self.logger.error(f"更新现货账户余额失败: {e}")
            return False
    
    def update_futures_balance(self, exchange: str, balance_data: Dict[str, Any]) -> bool:
        """
        更新合约账户余额
        
        Args:
            exchange: 交易所名称
            balance_data: 余额数据
            
        Returns:
            是否更新成功
        """
        try:
            account_key = f"{exchange}_futures"
            
            if account_key not in self._accounts_cache:
                self._accounts_cache[account_key] = {
                    'exchange': exchange,
                    'account_type': 'futures',
                    'balance': 0.0,
                    'equity': 0.0,
                    'margin': 0.0,
                    'available': 0.0,
                    'positions': {},
                    'last_update': 0
                }
            
            # 更新账户信息
            account = self._accounts_cache[account_key]
            account['balance'] = balance_data.get('balance', 0.0)
            account['equity'] = balance_data.get('equity', 0.0)
            account['margin'] = balance_data.get('margin', 0.0)
            account['available'] = balance_data.get('available', 0.0)
            account['positions'] = balance_data.get('positions', {})
            account['last_update'] = balance_data.get('update_time', int(time.time()))
            
            # 保存到文件
            self._save_accounts()
            
            self.logger.info(f"更新 {exchange} 合约账户余额成功")
            return True
            
        except Exception as e:
            self.logger.error(f"更新合约账户余额失败: {e}")
            return False
    
    def get_spot_balance(self, exchange: str) -> Optional[Dict[str, Any]]:
        """
        获取现货账户余额
        
        Args:
            exchange: 交易所名称
            
        Returns:
            现货账户余额信息
        """
        account_key = f"{exchange}_spot"
        return self._accounts_cache.get(account_key)
    
    def get_futures_balance(self, exchange: str) -> Optional[Dict[str, Any]]:
        """
        获取合约账户余额
        
        Args:
            exchange: 交易所名称
            
        Returns:
            合约账户余额信息
        """
        account_key = f"{exchange}_futures"
        return self._accounts_cache.get(account_key)
    
    def get_available_balance(self, exchange: str, account_type: str, currency: str = 'usdt') -> float:
        """
        获取可用余额
        
        Args:
            exchange: 交易所名称
            account_type: 账户类型 (spot/futures)
            currency: 币种
            
        Returns:
            可用余额
        """
        try:
            if account_type == 'spot':
                account = self.get_spot_balance(exchange)
                if account and 'balances' in account:
                    balance_info = account['balances'].get(currency.lower(), {})
                    return balance_info.get('available', 0.0)
            
            elif account_type == 'futures':
                account = self.get_futures_balance(exchange)
                if account:
                    return account.get('available', 0.0)
            
            return 0.0
            
        except Exception as e:
            self.logger.error(f"获取可用余额失败: {e}")
            return 0.0
    
    def get_total_balance(self, exchange: str, account_type: str, currency: str = 'usdt') -> float:
        """
        获取总余额
        
        Args:
            exchange: 交易所名称
            account_type: 账户类型 (spot/futures)
            currency: 币种
            
        Returns:
            总余额
        """
        try:
            if account_type == 'spot':
                account = self.get_spot_balance(exchange)
                if account and 'balances' in account:
                    balance_info = account['balances'].get(currency.lower(), {})
                    return balance_info.get('total', 0.0)
            
            elif account_type == 'futures':
                account = self.get_futures_balance(exchange)
                if account:
                    return account.get('equity', 0.0)
            
            return 0.0
            
        except Exception as e:
            self.logger.error(f"获取总余额失败: {e}")
            return 0.0
    
    def get_position(self, exchange: str, symbol: str) -> Optional[Dict[str, Any]]:
        """
        获取合约仓位信息
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            
        Returns:
            仓位信息
        """
        try:
            account = self.get_futures_balance(exchange)
            if account and 'positions' in account:
                return account['positions'].get(symbol.lower())
            
            return None
            
        except Exception as e:
            self.logger.error(f"获取仓位信息失败: {e}")
            return None
    
    def has_sufficient_balance(self, exchange: str, account_type: str, 
                              amount: float, currency: str = 'usdt') -> bool:
        """
        检查是否有足够余额
        
        Args:
            exchange: 交易所名称
            account_type: 账户类型
            amount: 需要的金额
            currency: 币种
            
        Returns:
            是否有足够余额
        """
        try:
            available = self.get_available_balance(exchange, account_type, currency)
            return available >= amount
            
        except Exception as e:
            self.logger.error(f"检查余额失败: {e}")
            return False
    
    def get_account_summary(self, exchange: str) -> Dict[str, Any]:
        """
        获取账户摘要信息
        
        Args:
            exchange: 交易所名称
            
        Returns:
            账户摘要
        """
        try:
            summary = {
                'exchange': exchange,
                'spot': {},
                'futures': {},
                'last_update': 0
            }
            
            # 现货账户信息
            spot_account = self.get_spot_balance(exchange)
            if spot_account:
                summary['spot'] = {
                    'balances_count': len(spot_account.get('balances', {})),
                    'last_update': spot_account.get('last_update', 0)
                }
                
                # 计算总价值（以USDT计算）
                total_usdt = 0.0
                for currency, balance_info in spot_account.get('balances', {}).items():
                    if currency == 'usdt':
                        total_usdt += balance_info.get('total', 0.0)
                
                summary['spot']['total_usdt_value'] = total_usdt
            
            # 合约账户信息
            futures_account = self.get_futures_balance(exchange)
            if futures_account:
                summary['futures'] = {
                    'equity': futures_account.get('equity', 0.0),
                    'available': futures_account.get('available', 0.0),
                    'margin': futures_account.get('margin', 0.0),
                    'positions_count': len(futures_account.get('positions', {})),
                    'last_update': futures_account.get('last_update', 0)
                }
            
            # 最后更新时间
            summary['last_update'] = max(
                summary['spot'].get('last_update', 0),
                summary['futures'].get('last_update', 0)
            )
            
            return summary
            
        except Exception as e:
            self.logger.error(f"获取账户摘要失败: {e}")
            return {}
    
    def get_all_accounts(self) -> Dict[str, Any]:
        """
        获取所有账户信息
        
        Returns:
            所有账户信息
        """
        return self._accounts_cache.copy()
    
    def clear_account_cache(self, exchange: str = None) -> None:
        """
        清理账户缓存
        
        Args:
            exchange: 交易所名称，如果为None则清理所有
        """
        try:
            if exchange:
                # 清理指定交易所的账户
                keys_to_remove = [key for key in self._accounts_cache.keys() 
                                if key.startswith(f"{exchange}_")]
                
                for key in keys_to_remove:
                    del self._accounts_cache[key]
                
                self.logger.info(f"清理了 {exchange} 的账户缓存")
            else:
                # 清理所有账户
                self._accounts_cache.clear()
                self.logger.info("清理了所有账户缓存")
            
            # 保存到文件
            self._save_accounts()
            
        except Exception as e:
            self.logger.error(f"清理账户缓存失败: {e}")
    
    def is_account_data_fresh(self, exchange: str, account_type: str, 
                             max_age_seconds: int = 300) -> bool:
        """
        检查账户数据是否新鲜
        
        Args:
            exchange: 交易所名称
            account_type: 账户类型
            max_age_seconds: 最大过期时间（秒）
            
        Returns:
            数据是否新鲜
        """
        try:
            account_key = f"{exchange}_{account_type}"
            account = self._accounts_cache.get(account_key)
            
            if not account:
                return False
            
            last_update = account.get('last_update', 0)
            current_time = int(time.time())
            
            return (current_time - last_update) <= max_age_seconds
            
        except Exception as e:
            self.logger.error(f"检查账户数据新鲜度失败: {e}")
            return False